package com.ruoyi.quartz.task;

import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Maps;
import com.google.common.util.concurrent.RateLimiter;
import com.jlx.distribution.api.Distribution;
import com.jlx.distribution.pojo.common.RequestContext;
import com.jlx.distribution.pojo.common.passenger.refund.BaseRefundPassenger;
import com.jlx.distribution.pojo.endorse.*;
import com.jlx.distribution.pojo.payok.input.PayOkParam;
import com.jlx.distribution.pojo.payok.output.PayOkResult;
import com.jlx.distribution.pojo.refund.confirm.ConfirmRefundTicketRequest;
import com.jlx.distribution.pojo.refund.confirm.ConfirmRefundTicketResponse;
import com.jlx.distribution.pojo.refund.fee.QueryRefundTicketFeeRequest;
import com.jlx.distribution.pojo.refund.fee.QueryRefundTicketFeeResponse;
import com.jlx.distribution.pojo.search.input.SearchCondition;
import com.jlx.distribution.pojo.search.input.SearchParam;
import com.jlx.distribution.pojo.search.input.Segment;
import com.jlx.distribution.pojo.search.output.SearchResult;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.pojo.BatchRefreshRequest;
import com.ruoyi.common.pojo.change.JlxChangeData;
import com.ruoyi.common.pojo.change.JlxChangeOrder;
import com.ruoyi.common.pojo.change.JlxChangeResult;
import com.ruoyi.common.pojo.order.JlxListResponse;
import com.ruoyi.common.pojo.order.JlxOrderBean;
import com.ruoyi.common.pojo.order.JlxPassenger;
import com.ruoyi.common.pojo.refund.JlxRefundData;
import com.ruoyi.common.pojo.refund.JlxRefundOrder;
import com.ruoyi.common.pojo.refund.JlxRefundResult;
import com.ruoyi.common.utils.*;
import com.ruoyi.system.domain.OrderInfo;
import com.ruoyi.system.domain.RefundChangeInfo;
import com.ruoyi.system.service.IOrderInfoService;
import com.ruoyi.system.service.IRefundChangeInfoService;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.compress.utils.Lists;
import org.apache.commons.lang.math.NumberUtils;
import org.joda.time.DateTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * 定时任务调度测试
 *
 * @author ruoyi
 */
@Component("ryTask")
public class RyTask
{
    private static final Logger logger = LoggerFactory.getLogger(RyTask.class);

    @Autowired
    private Distribution distribution;

    @Autowired
    private RedisCache redisCache;

    @Autowired
    private IOrderInfoService orderInfoService;

    @Autowired
    private IRefundChangeInfoService refundChangeInfoService;

    public void ryMultipleParams(String s, Boolean b, Long l, Double d, Integer i)
    {
        System.out.println(StringUtils.format("执行多参方法： 字符串类型{}，布尔类型{}，长整型{}，浮点型{}，整形{}", s, b, l, d, i));
    }

    public void ryParams(String params)
    {
        System.out.println("执行有参方法：" + params);
    }

    public void ryNoParams()
    {
        System.out.println("执行无参方法");
    }

    public void synRefund()
    {
        String orderListUrl ="http://fuwu.jiulvxing.com/autoOta/servOrderExport";
        Map<String, Object> paramMap = Maps.newHashMap();
        paramMap.put("domain","kya");
        paramMap.put("user","kya");
        paramMap.put("pass","kya");
        paramMap.put("type","incr");
        paramMap.put("servType",0);
        paramMap.put("status",1);
        paramMap.put("start", DateTime.now().plusHours(-1).toString("yyyy-MM-dd HH:mm:ss"));
        paramMap.put("end",DateTime.now().toString("yyyy-MM-dd HH:mm:ss"));
        logger.info("退票:就旅行批量导单接口参数:参数={},请求地址={}", JSONObject.toJSONString(paramMap), orderListUrl);
        String result = HttpUtil.get(orderListUrl,paramMap);
        if (org.apache.commons.lang.StringUtils.isBlank(result)) {
            logger.warn("退票:就旅行批量导单接口结果:空,参数={}", JSONObject.toJSONString(paramMap));
            return;
        }
        JlxRefundResult jlxRefundResult=JSONObject.parseObject(result,JlxRefundResult.class);
        if (!jlxRefundResult.isRet()||CollectionUtils.isEmpty(jlxRefundResult.getData())) {
            logger.warn("退票:就旅行批量导单接口结果:空,结果={}", result);
            return;
        }
        for(JlxRefundData jlxRefundData:jlxRefundResult.getData()){
            try{
                String key="Refund_"+jlxRefundData.getOrderNo()+jlxRefundData.getServOrderNo();
                if(redisCache.getCacheObject(key)!=null){
                    continue;
                }

                OrderInfo orderInfo=new OrderInfo();
                orderInfo.setOrderNo(jlxRefundData.getOrderNo());
                List<OrderInfo> orderInfos =orderInfoService.selectOrderInfoList(orderInfo);
                if(CollectionUtils.isEmpty(orderInfos)){
                    continue;
                }

                ConfirmRefundTicketRequest confirmRefundTicketRequest=new ConfirmRefundTicketRequest();
                confirmRefundTicketRequest.setContext(buildDefaultContext());
                confirmRefundTicketRequest.setOrderNo(orderInfos.get(0).getOuterOrderNo());
                confirmRefundTicketRequest.setApplyType(StringUtils.equals("非自愿",jlxRefundData.getServOrders().get(0).getRefundType())?2:1);
                List<BaseRefundPassenger> passengers= Lists.newArrayList();
               /* QueryOrderRequest req=new QueryOrderRequest();
                req.setContext(RequestContextUtil.buildDefaultContext());
                req.setOrderNo(jlxRefundData.getOrderNo());
                OrderDetail orderDetail= distribution.orderDetail(req);*/
                JlxOrderBean jlxOrderBean=getJLXOrderInfo(jlxRefundData.getOrderNo());
                if(jlxOrderBean==null){
                    continue;
                }
                for(JlxRefundOrder jlxRefundOrder:jlxRefundData.getServOrders()){
                    BaseRefundPassenger passenger=new BaseRefundPassenger();
                    passenger.setName(jlxRefundOrder.getPassenger());
                    for(JlxPassenger passenger1: jlxOrderBean.getPassenger()){
                        if(StringUtils.equals(passenger1.getName(),passenger.getName())){
                            passenger.setCardType(passenger1.getCardType());
                            passenger.setCardNum(passenger1.getCardNum());
                        }
                    }
                    passengers.add(passenger);
                }

                if(confirmRefundTicketRequest.getApplyType()==1){
                    QueryRefundTicketFeeRequest queryRefundTicketFeeRequest=new QueryRefundTicketFeeRequest();
                    queryRefundTicketFeeRequest.setContext(buildDefaultContext());
                    queryRefundTicketFeeRequest.setOrderNo(orderInfos.get(0).getOuterOrderNo());
                    queryRefundTicketFeeRequest.setApplyType(1);
                    queryRefundTicketFeeRequest.setReason("自愿");
                    queryRefundTicketFeeRequest.setPassengers(passengers);
                    QueryRefundTicketFeeResponse queryRefundTicketFeeResponse= distribution.queryRefundFee(queryRefundTicketFeeRequest);

                    if(queryRefundTicketFeeResponse!=null&&queryRefundTicketFeeResponse.getStatus().getCode()==0&&CollectionUtils.isNotEmpty(queryRefundTicketFeeResponse.getPassengers())){
                        BigDecimal refundAmount=  queryRefundTicketFeeResponse.getPassengers().get(0).getFlights().get(0).getRefundAmount();
                        int refundAmountLimit= NumberUtils.toInt(redisCache.getCacheObject("refund_amount_limit"),0);
                        if(refundAmount.intValue()<=refundAmountLimit){
                            continue;
                        }
                    }

                    if(redisCache.getCacheObject("ziyuan_refund")!=null){
                        if(!StringUtils.equals("REFUND_NO_TICKET",jlxOrderBean.getStatus())){
                            continue;
                        }
                    }
                }


                confirmRefundTicketRequest.setReason(StringUtils.equals("非自愿",jlxRefundData.getServOrders().get(0).getRefundType())?"航班延误或取消、航班时刻变更":"改变行程，不想飞了");
                confirmRefundTicketRequest.setPassengers(passengers);
                ConfirmRefundTicketResponse refundTicketResponse=distribution.confirmRefund(confirmRefundTicketRequest);
                if(refundTicketResponse!=null&&refundTicketResponse.getStatus().getCode()==0){
                    RefundChangeInfo refundChangeInfo=new RefundChangeInfo();
                    refundChangeInfo.setType(0);
                    refundChangeInfo.setOrderNo(jlxRefundData.getOrderNo());
                    refundChangeInfo.setServiceOrderId(Integer.parseInt(jlxRefundData.getServOrderNo()));
                    refundChangeInfo.setOuterOrderNo(confirmRefundTicketRequest.getOrderNo());
                    refundChangeInfo.setOuterServiceOrderId(Integer.parseInt(refundTicketResponse.getServiceOrderNo()));
                    refundChangeInfo.setCreateTime(new Date());
                    refundChangeInfoService.insertRefundChangeInfo(refundChangeInfo);
                    redisCache.setCacheObject(key,"true",24, TimeUnit.HOURS);
                }
            }catch (Exception e){
                logger.error("syn refund error {}",jlxRefundData.getOrderNo(),e);
            }
        }
        logger.debug("退票:就旅行批量导单接口结果:参数={},结果={}", JSONObject.toJSONString(paramMap), result);
    }

    public void synChange()
    {
        String orderListUrl = "http://fuwu.jiulvxing.com/autoOta/servOrderExport";
        Map<String, Object> paramMap = Maps.newHashMap();
        paramMap.put("domain","kya");
        paramMap.put("user","kya");
        paramMap.put("pass","kya");
        paramMap.put("type","incr");
        paramMap.put("servType",1);
        paramMap.put("start", DateTime.now().plusHours(-1).toString("yyyy-MM-dd HH:mm:ss"));
        paramMap.put("end",DateTime.now().toString("yyyy-MM-dd HH:mm:ss"));
        logger.info("改期:就旅行单个导单接口参数:参数={},请求地址={}", JSONObject.toJSONString(paramMap), orderListUrl);
        String result = HttpUtil.get(orderListUrl,paramMap);
        if (org.apache.commons.lang.StringUtils.isBlank(result)) {
            logger.warn("改期:就旅行单个导单接口结果:空,参数={}", JSONObject.toJSONString(paramMap));
            return;
        }
        logger.info("改期:就旅行单个导单接口结果:参数={},结果={}", JSONObject.toJSONString(paramMap), result);
        JlxChangeResult jlxChangeResult=JSONObject.parseObject(result,JlxChangeResult.class);
        if (!jlxChangeResult.isRet()||CollectionUtils.isEmpty(jlxChangeResult.getData())) {
            logger.warn("改期:就旅行批量导单接口结果:空,结果={}", result);
            return;
        }
        for(JlxChangeData jlxChangeData:jlxChangeResult.getData()){
            try{
                String key="Change_"+jlxChangeData.getOrderNo()+jlxChangeData.getServOrderNo();
                if(redisCache.getCacheObject(key)!=null||!StringUtils.equals("支付待改期",jlxChangeData.getServOrderStatus())){
                    continue;
                }

                OrderInfo orderInfo=new OrderInfo();
                orderInfo.setOrderNo(jlxChangeData.getOrderNo());
                List<OrderInfo> orderInfos =orderInfoService.selectOrderInfoList(orderInfo);
                if(CollectionUtils.isEmpty(orderInfos)){
                    continue;
                }
                ChgFlightSearchReq flightChangeRequest=new ChgFlightSearchReq();
                flightChangeRequest.setContext(buildDefaultContext());
                flightChangeRequest.setOrderNo(orderInfos.get(0).getOuterOrderNo());
                flightChangeRequest.setApplyType(StringUtils.equals("非自愿",jlxChangeData.getServOrders().get(0).getChangeType())?2:1);
                flightChangeRequest.setReason(StringUtils.equals("非自愿",jlxChangeData.getServOrders().get(0).getChangeType())?7:5);
                List<ChgCityPair> chageItem=Lists.newArrayList();
                flightChangeRequest.setChageItem(chageItem);
                ChgCityPair chgCityPair=new ChgCityPair();
                chgCityPair.setDepAirportCode(jlxChangeData.getServOrders().get(0).getDep());
                chgCityPair.setArrAirportCode(jlxChangeData.getServOrders().get(0).getArr());
                chgCityPair.setDepartureDate(jlxChangeData.getServOrders().get(0).getDepTime().substring(0,10));
                chageItem.add(chgCityPair);
                ChgFlightSearchRes chgFlightSearchRes = distribution.searchChgFlight(flightChangeRequest);
                String changeKey=null;
                String lowestChangeKey=null;
                int lowestAmount=99999;
                for(ChgFlightSearchPair chgFlightSearchPair : chgFlightSearchRes.getAvResultList()){
                    for(ChgFlightInfo chgFlightInfo:chgFlightSearchPair.getTripFlightList()){
                        if(chgFlightInfo.getFlightNum().equalsIgnoreCase(jlxChangeData.getServOrders().get(0).getFlightNum())){
                            for(ChgCabinInfo chgCabinInfo:chgFlightInfo.getCabinList()){
                                if(chgCabinInfo.getCabin().equalsIgnoreCase(jlxChangeData.getServOrders().get(0).getCabin())){
                                    changeKey=chgCabinInfo.getKey();
                                }
                                if(new BigDecimal(chgCabinInfo.getPayAmountAdt()).intValue()<lowestAmount){
                                    lowestAmount=new BigDecimal(chgCabinInfo.getPayAmountAdt()).intValue();
                                    lowestChangeKey=chgCabinInfo.getKey();
                                }
                            }
                        }
                    }
                }

                if(changeKey==null){
                    changeKey=lowestChangeKey;
                }

                if(changeKey!=null){
                    ChgCreateOrderReq chgCreateOrderReq=new ChgCreateOrderReq();
                    chgCreateOrderReq.setContext(buildDefaultContext());
                    chgCreateOrderReq.setOrderNo(orderInfos.get(0).getOuterOrderNo());
                    List<ChgAirOriDest> changeAirOriDestList=Lists.newArrayList();
                    chgCreateOrderReq.setChangeAirOriDestList(changeAirOriDestList);
                    ChgAirOriDest chgAirOriDest=new ChgAirOriDest();
                    chgAirOriDest.setDepAirportCode(jlxChangeData.getServOrders().get(0).getDep());
                    chgAirOriDest.setArrAirportCode(jlxChangeData.getServOrders().get(0).getArr());
                    chgAirOriDest.setOriDepartDate(jlxChangeData.getServOrders().get(0).getOriDepTime().substring(0,10));
                    changeAirOriDestList.add(chgAirOriDest);
                    List<ChgFlightCabinDto> changeFlightCabinDtoList=Lists.newArrayList();
                    chgAirOriDest.setChangeFlightCabinDtoList(changeFlightCabinDtoList);
                    for(JlxChangeOrder jlxChangeOrder:jlxChangeData.getServOrders()){
                        ChgFlightCabinDto chgFlightCabinDto=new ChgFlightCabinDto();
                        chgFlightCabinDto.setKey(changeKey);
                        chgFlightCabinDto.setName(jlxChangeOrder.getPassenger());
                        chgFlightCabinDto.setAgeType(Integer.parseInt(jlxChangeOrder.getPassengerType()));
                        chgFlightCabinDto.setCardType(jlxChangeOrder.getCardType());
                        chgFlightCabinDto.setCardNum(jlxChangeOrder.getCardNum());
                        changeFlightCabinDtoList.add(chgFlightCabinDto);
                    }
                    ChgCreateOrderRes chgCreateOrderRes = distribution.createChangeOrder(chgCreateOrderReq);
                    if(chgCreateOrderRes!=null&&chgCreateOrderRes.getStatus().getCode()==0){
                        Thread.currentThread().sleep(1000);
                        ChgDetailReq chgDetailReq=new ChgDetailReq();
                        chgDetailReq.setContext(RequestContextUtil.buildDefaultContext());
                        chgDetailReq.setOrderNo(chgCreateOrderRes.getSubOrderNo());
                        ChgDetailRes chgDetailRes = distribution.queryChangeDetail(chgDetailReq);

                        PayOkParam payOkParam=new PayOkParam();
                        payOkParam.setContext(buildDefaultContext());
                        payOkParam.setOrderNo(chgCreateOrderRes.getSubOrderNo());
                        payOkParam.setPayAmount(new BigDecimal(chgDetailRes.getTotalPrice()));
                        if(new BigDecimal(chgDetailRes.getTotalPrice()).doubleValue()-jlxChangeData.getPrice()<50){
                            PayOkResult payOkResult = distribution.payOk(payOkParam);
                           /* if(payOkResult!=null&&payOkResult.getStatus().getCode()==0){

                            }*/
                        }
                        RefundChangeInfo refundChangeInfo=new RefundChangeInfo();
                        refundChangeInfo.setType(1);
                        refundChangeInfo.setOrderNo(jlxChangeData.getOrderNo());
                        refundChangeInfo.setServiceOrderId(Integer.parseInt(jlxChangeData.getServOrderNo()));
                        refundChangeInfo.setOuterOrderNo(chgCreateOrderRes.getOrderNo());
                        refundChangeInfo.setOuterServiceOrderId(ChangeOrderUtil.decodeServOrderId(chgCreateOrderRes.getSubOrderNo()));
                        refundChangeInfo.setCreateTime(new Date());
                        refundChangeInfoService.insertRefundChangeInfo(refundChangeInfo);
                        redisCache.setCacheObject(key,"true",24, TimeUnit.HOURS);
                    }
                }
            }catch (Exception e){
                logger.error("syn change error {}",jlxChangeData.getOrderNo(),e);
            }
        }
        logger.debug("改期:就旅行单个导单接口结果:参数={},结果={}", JSONObject.toJSONString(paramMap), result);
        return;
    }

    public RequestContext buildDefaultContext() {
        RequestContext context = new RequestContext();
        context.setVersion("1.0.0");
        long time = System.currentTimeMillis();
        String nonce = UUID.randomUUID().toString().replaceAll("-", "");
//        String key = QConfigUtils.getConfig("default.context.key." + channel, "16868419445b43c5b935c596a528cbdf");
        String cacheKey = "95a51552a1d643d2a2b72917dd315176";
        String sign = DigestUtils.md5Hex(nonce + cacheKey + time);
        context.setTimestamp(time);
        context.setChannel("kuyou");
        context.setSign(sign);
        context.setNonce(nonce);
        return context;
    }

    public void cachePrice(){
        String [] airlines= Constants.AIRLINES.split("&");
        DateTime today=DateTime.now();
        RateLimiter rateLimiter =RateLimiter.create(20);
        for(String airline:airlines){
            String dpt=airline.split("-")[0];
            String arr=airline.split("-")[1];
            for(int i=3;i<=30;i++){
                rateLimiter.acquire();
                String date=today.plusDays(i).toString("yyyy-MM-dd");
                AsyncWorker.execute(() -> {
                    SearchParam searchParam=new SearchParam();
                    SearchCondition searchCondition=new SearchCondition();
                    searchParam.setSearchCondition(searchCondition);
                    Segment segment=new Segment();
                    segment.setDep(dpt);
                    segment.setArr(arr);
                    segment.setDate(date);
                    segment.setCarrier(Constants.CARRIER);
                    searchCondition.setSegments(com.google.common.collect.Lists.newArrayList(segment));
                    searchParam.setContext(buildDefaultContext());
                    SearchResult searchResult=distribution.search(searchParam);
                    if (searchResult != null&& searchResult.getSearchResponse()!=null && CollectionUtils.isNotEmpty(searchResult.getSearchResponse().getFlightProductGroup())) {
                        redisCache.setCacheObject(dpt+arr+date,searchResult,Constants.CACHE_TIMEOUT, TimeUnit.SECONDS);
                    }/*else {
                        redisCache.deleteObject(dpt+arr+date);
                    }*/
               });
            }
        }
    }

    public void refreshCache(){
        String [] airlines= Constants.AIRLINES.split("&");
        DateTime today=DateTime.now();
        //RateLimiter rateLimiter =RateLimiter.create(1);
        List<BatchRefreshRequest.FlightKey> list= Lists.newArrayList();
        for(String airline:airlines){
            String dpt=airline.split("-")[0];
            String arr=airline.split("-")[1];
            for(int i=3;i<=30;i++){
                String date=today.plusDays(i).toString("yyyyMMdd");
                BatchRefreshRequest.FlightKey flightKey=new BatchRefreshRequest.FlightKey();
                flightKey.setDptAirport(dpt);
                flightKey.setArrAirport(arr);
                flightKey.setDate(date);
                list.add(flightKey);
                if(list.size()==1000){
                    //rateLimiter.acquire();
                    BatchRefreshRequest refreshRequest=new BatchRefreshRequest();
                    refreshRequest.setDomain("kya");
                    refreshRequest.setSecretKey("a398e9b0-0446-420a-a98f-ec7805702511");
                    refreshRequest.setFlights(list);
                    logger.debug("refresh batch cache param : {}",JSONObject.toJSONString(refreshRequest));
                    String response= HttpUtil.post("http://agentfare.jiulvxing.com/afare/refresh/batch/cache", JSONObject.toJSONString(refreshRequest));
                    logger.debug("refresh batch cache response : {}",response);
                    list=Lists.newArrayList();
                }
            }
        }
    }

    public JlxOrderBean getJLXOrderInfo(String orderNo){
        try {
            String orderListUrl = "http://fuwu.jiulvxing.com/autoOta/orderExport";
            Map<String, Object> paramMap = Maps.newHashMap();
            paramMap.put("domain","kya");
            paramMap.put("user","kya");
            paramMap.put("pass","kya");
            paramMap.put("type","exact");
            paramMap.put("orderNo",orderNo);
            logger.info("getJLXOrderInfo param : {}",JSONObject.toJSONString(paramMap));
            String result = HttpUtil.get(orderListUrl, paramMap);
            logger.info("getJLXOrderInfo result :{} {}",orderNo,result);
            JlxListResponse jlxListResponse=JaxbXmlUtil.converyToJavaBean(result,JlxListResponse.class);
            if(jlxListResponse!=null&&CollectionUtils.isNotEmpty(jlxListResponse.getOrder())){
                return jlxListResponse.getOrder().get(0);
            }
        }catch (Exception e){
            logger.error("getJLXOrderInfo error {}",orderNo,e);
        }
        return null;
    }


    public static void main(String[] args) {
        String orderListUrl = "http://fuwu.jiulvxing.com/autoOta/orderExport";
        Map<String, Object> paramMap = Maps.newHashMap();
        paramMap.put("domain","kya");
        paramMap.put("user","kya");
        paramMap.put("pass","kya");
        paramMap.put("type","exact");
        paramMap.put("orderNo","5228253627794");
        String result = HttpUtil.get(orderListUrl, paramMap);
        JlxListResponse jlxListResponse=JaxbXmlUtil.converyToJavaBean(result,JlxListResponse.class);
    }

}
